
/// <reference path="./../utils/EventDispatcher.ts" />
/// <reference path="./../utils/Maps.ts" />
/// <reference path="./BaseModule.ts" />

namespace apeng {


	/**数据管理 避免数据模块之间循环引用 */
	class ModuleMgr extends EventDispatcher {

		public readonly EventType = {
			/**启动队列 */
			START_UP: "START_UP",
			CREATE_COMLETE: "CREATE_COMLETE",
		}

		private _addModules: { [moduleType: number]: new () => BaseModule } = {}
		private modules: { [moduleType: number]: BaseModule } = {}

		public modelTypeOrgin: any = null!

		public add(moduleType: number) {
			return function (target: new () => BaseModule) {
				moduleMgr._addModules[moduleType] = target
				// if (moduleMgr.modelTypeOrgin)
				// 	console.log("add module: ", moduleMgr.modelTypeOrgin[moduleType])
				// else
				// 	console.log("add module: ", moduleType)
			}
		}

		/**获取实例化后的模块 */
		public get<T extends BaseModule>(moduleType: number): T {
			return this.modules[moduleType] as T
		}

		/**实例化时 */
		public instance() {
			console.log("module count:" + Maps.size(this._addModules))
			Maps.forEach(this._addModules, (module, moduleName) => {
				let value = this.modules[moduleName as any] = new module()
				value.moduleType = Number(moduleName)
				if (value.onInstance)
					value.onInstance()
			})
		}

		public forEach(cb: (module: BaseModule) => void) {
			Maps.forEach(this.modules, cb)
		}

		public run(complete: () => void, _enum?: any) {
			console.log("module START_UP start")
			this.emitQueue(this.EventType.START_UP, -1, () => {
				console.log("module START_UP complete")
				Maps.forEach(this.modules, module => {
					if (module.onCreate)
						module.onCreate()
				})
				Maps.forEach(this.modules, module => {
					if (module.onLogic)
						module.onLogic()
				})
				Maps.forEach(this.modules, module => {
					if (module.onComplete)
						module.onComplete()
				})
				complete()

				this.emit(this.EventType.CREATE_COMLETE)
			}, _enum ? ((index) => "START_UP " + _enum[index]) : "START_UP")
		}


	}

	export const moduleMgr = new ModuleMgr()
}